package ch.netcetera.planningpoker.client.ui.participant.play;

import java.util.logging.Level;
import java.util.logging.Logger;

import ch.netcetera.planningpoker.client.model.GameProxy;
import ch.netcetera.planningpoker.client.model.ParticipantProxy;
import ch.netcetera.planningpoker.client.ui.events.ChannelEventHelper;
import ch.netcetera.planningpoker.client.ui.events.RoundStatusChangedEvent;
import ch.netcetera.planningpoker.client.ui.events.UserListChangedEvent;
import ch.netcetera.planningpoker.client.ui.main.MainPagePresenter;
import ch.netcetera.planningpoker.client.ui.round.RoundPresenter;
import ch.netcetera.planningpoker.client.ui.widget.userlist.UserListPresenter;
import ch.netcetera.planningpoker.shared.GameRequestFactory;

import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;

public class PlayPresenter extends
        Presenter<PlayPresenter.IView, PlayPresenter.IProxy> {

    private static final Logger logger = Logger.getLogger(PlayPresenter.class
            .getName());

    public static final String NAME_TOKEN = "play";
    public static final String ARG_GAME_ID = "gameId";
    public static final String ARG_PARTICIPANT_ID = "participantId";

    @ProxyCodeSplit
    @NameToken(NAME_TOKEN)
    public interface IProxy extends ProxyPlace<PlayPresenter> {

    }

    public interface IView extends View {

        HasText getGameTitle();

        HasText getParticipant();

        HasWidgets getAllParticipants();
        
        HasWidgets getCurrentRound();

    }

    private GameRequestFactory requestFactory;


    private Long gameId;

    private UserListPresenter userListPresenter;

    private RoundPresenter roundPresenter;

    @Inject
    public PlayPresenter(EventBus eventBus, 
            IView view, IProxy proxy, GameRequestFactory requestFactory, UserListPresenter userListPresenter, RoundPresenter roundPresenter) {
        super(true, eventBus, view, proxy);
        this.requestFactory = requestFactory;
        this.userListPresenter = userListPresenter;
        this.roundPresenter = roundPresenter;
    }

    @Override
    public void prepareFromRequest(PlaceRequest request) {
        super.prepareFromRequest(request);

        String gameIdString = request.getParameter(ARG_GAME_ID, "");

        logger.info("Landed on playview with argument gameId : " + gameIdString);

        try {
            gameId = Long.valueOf(gameIdString);
        } catch (NumberFormatException e) {
            logger.log(Level.SEVERE, "parsing parameter failed", e);
        }

        String participantIdString = request.getParameter(ARG_PARTICIPANT_ID,
                "");

        logger.info("Landed on playview with argument participantId : "
                + participantIdString);

        Long participantId = null; 
        try {
            participantId = Long.valueOf(participantIdString);
        } catch (NumberFormatException e) {
            logger.log(Level.SEVERE, "parsing parameter failed", e);
            // TODO add error to gui
        }

        if (gameId != null) {
            requestFactory.getGameRequest().findGame(gameId)
                    .fire(new Receiver<GameProxy>() {

                        @Override
                        public void onSuccess(GameProxy game) {
                            getView().getGameTitle().setText(game.getTitle());
                        }
                    });
        }

        if (participantId != null) {
            requestFactory.getParticipantRequest().get(participantId)
                    .fire(new Receiver<ParticipantProxy>() {

                        @Override
                        public void onSuccess(ParticipantProxy p) {
                            curParticipantLoaded(p);
                        }
                    });
        }

        if (gameId != null) {
            getEventBus().fireEventFromSource(new UserListChangedEvent(gameId), this);
            getEventBus().fireEventFromSource(new RoundStatusChangedEvent(gameId), this);
        }
        
    }

    @Override
    protected void onBind() {
        getView().getAllParticipants().add(userListPresenter.getWidget());
        getView().getCurrentRound().add(roundPresenter.getWidget());
    }

    @Override
    protected void revealInParent() {
        RevealContentEvent.fire(this, MainPagePresenter.MainContentSlot, this);
    }
    
    private void curParticipantLoaded(ParticipantProxy p) {
        getView().getParticipant().setText(
                p.getName());
        ChannelEventHelper.registerChannelEventListener(getEventBus(), p.getChannelToken());
    }

}
